﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 创建者：王明亮
 * 创建时间：2022/9/20 19:44:03
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Aliang.Common.Helper.TypeConvert
{
    /// <summary>
    /// ByteConvertHelper 字节相关转换帮助类
    /// </summary>
    public class ByteConvertHelper
    {


        /// <summary>
        /// 二进制字符串转为十六进制数组
        /// </summary>
        /// <param name="orgStr"></param>
        /// <returns></returns>
        public static byte[] BitsToBytes(string orgStr)
        {
            byte[] result = null;
            if (orgStr.Length > 8)
            {
                int len = orgStr.Length % 8 == 0 ? orgStr.Length / 8 : (orgStr.Length / 8) + 1;
                result = new byte[len];
                string tempStr = orgStr.PadLeft((8 - orgStr.Length % 8) + orgStr.Length, '0');
                for (int i = 0; i < len; i++)
                {
                    string binStr;

                    binStr = tempStr.Substring(i * 0, 8);
                    tempStr = tempStr.Substring(8, tempStr.Length - 8);

                    result[i] = Convert.ToByte(binStr, 2);
                }
            }
            else
            {
                result = new byte[1];
                result[0] = Convert.ToByte(orgStr, 2);
            }

            return result;
        }
        /// <summary>
        /// byte数组转16进制字符串
        /// </summary>
        /// <param name="data">byte数组</param>
        /// <returns></returns>
        public static string ByteArrayToHexString(byte[] data)
        {
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
            {
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0'));
            }
            return sb.ToString().ToUpper();
        }


        /// <summary>
        /// 16进制字符串转byte数组
        /// </summary>
        /// <param name="hexString">16进制字符</param>
        /// <returns></returns>

        public static byte[] ByteArrayToHexString(string hexString, string spiltChar = " ")
        {
            if (!string.IsNullOrEmpty(spiltChar))
            {
                hexString = hexString.Replace(spiltChar, "");
            }

            //将16进制秘钥转成字节数组
            var byteArray = new byte[hexString.Length / 2];
            for (var x = 0; x < byteArray.Length; x++)
            {
                var i = Convert.ToInt32(hexString.Substring(x * 2, 2), 16);
                byteArray[x] = (byte)i;
            }
            return byteArray;
        }


        /// <summary>
        /// byte数组中取double数值，本方法适用于(低位在前，高位在后)的顺序
        /// </summary>
        /// <param name="src">byte数组</param>
        /// <param name="offset">从数组的第offset位开始</param>
        /// <returns>double数值</returns>
        public static double bytesToDouble1(byte[] src, int offset)
        {
            int value;
            value = (int)((src[offset] & 0xFF)
                    | ((src[offset + 1] & 0xFF) << 8)
                    | ((src[offset + 2] & 0xFF) << 16)
                    | ((src[offset + 3] & 0xFF) << 24));
            return value * 1.0;
        }

        /// <summary>
        /// byte数组中取double数值，本方法适用于(高位在前，低位在后)的顺序
        /// </summary>
        /// <param name="src">byte数组</param>
        /// <param name="offset">从数组的第offset位开始</param>
        /// <returns>double数值</returns>
        public static double bytesToDouble2(byte[] src, int offset)
        {
            double value;
            value = BitConverter.ToInt32(new byte[] { src[offset++], src[offset++], src[offset++], src[offset] }, 0) * 1.0;
            return value;
        }


        /// <summary>
        /// byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序
        /// </summary>
        /// <param name="src">byte数组</param>
        /// <param name="offset">从数组的第offset位开始</param>
        /// <returns>int数值</returns>
        public static int bytesToInt(byte[] src, int offset)
        {
            int value;
            value = (int)((src[offset] & 0xFF)
                    | ((src[offset + 1] & 0xFF) << 8)
                    | ((src[offset + 2] & 0xFF) << 16)
                    | ((src[offset + 3] & 0xFF) << 24));
            return value;
        }

        /// <summary>
        /// byte数组中取int数值，本方法适用于(低位在后，高位在前)的顺序
        /// </summary>
        /// <param name="src"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static int bytesToInt2(byte[] src, int offset)
        {
            int value;
            value = (int)(((src[offset] & 0xFF) << 24)
                    | ((src[offset + 1] & 0xFF) << 16)
                    | ((src[offset + 2] & 0xFF) << 8)
                    | (src[offset + 3] & 0xFF));
            return value;
        }

        /// <summary>
        /// 将2个byte数转换为short,即16位有符合的数
        /// </summary>
        /// <param name="low">低位</param>
        /// <param name="high">高为</param>
        /// <returns>结果</returns>
        public static short bytesToInt16(byte high, byte low)
        {
            short value = 0;
            if ((high & 0x80) > 0)
            {
                value = (short)((-1) * ((high & 0x7F) * 0x100 + low));
            }
            else
            {
                value = (short)(high * 0x100 + low);
            }
            return value;
        }

        /// <summary>
        /// 将Uint的数转换为Double类型的数
        /// </summary>
        /// <param name="intValue">UInt类型的数据</param>
        /// <param name="pointBit">小数位数</param>
        /// <returns></returns>
        public static double IntToDouble(UInt32 intValue, byte pointBit)
        {
            double value = 0;

            value = intValue / Math.Pow(10, pointBit);

            return value;
        }


        #region Command
        /// <summary>
        /// 将指定进制的字符串转换到指定进制的字符串
        /// </summary>
        /// <param name="value">要转换的字符串</param>
        /// <param name="fromBase">value 中数字的基数，它必须是 2、8、10 或 16。</param>
        /// <param name="toBase">value 中数字的基数，它必须是 2、8、10 或 16。</param>
        /// <returns></returns>
        public static string ToString(string value, int fromBase, int toBase)
        {
            return Convert.ToString(Convert.ToInt32(value, fromBase), toBase);
        }

        /// <summary>
        /// 将字节数组节转换成指定进制的字符串
        /// </summary>
        /// <param name="byteArray">要转换的字符串</param>
        /// <param name="toBase">它必须是 2 或 16</param>
        /// <returns></returns>
        public static string ToString(byte[] byteArray, int toBase = 16)
        {
            if (byteArray == null || byteArray.Length == 0)
                return string.Empty;

            switch (toBase)
            {
                case 2:
                    return ByteArrayToBinaryString(byteArray);
                case 16:
                    return ByteArrayToHexStr(byteArray);
                default:
                    return string.Empty;
            }
        }

        /// <summary>
        /// 将指定进制的字符串转换成字节数组
        /// </summary>
        /// <param name="value"></param>
        /// <param name="fromBase"></param>
        /// <returns></returns>
        public static byte[] ToByteArray(string value, int fromBase = 16)
        {
            if (string.IsNullOrEmpty(value))
                return null;
            switch (fromBase)
            {
                case 2:
                    return BinaryStringToByteArray(value);
                case 16:
                    return HexStrToByteArray(value);
                default:
                    return null;
            }
        }

        /// <summary>
        /// 字节数组节转换成二进制字符串
        /// </summary>
        /// <param name="b">要转换的字节数组</param>
        /// <returns></returns>
        private static string ByteArrayToBinaryString(byte[] byteArray)
        {
            int capacity = byteArray.Length * 8;
            StringBuilder sb = new StringBuilder(capacity);
            for (int i = 0; i < byteArray.Length; i++)
            {
                sb.Append(byte2BinString(byteArray[i]));
            }
            return sb.ToString();
        }

        private static string byte2BinString(byte b)
        {
            return Convert.ToString(b, 2).PadLeft(8, '0');
        }

        /// <summary>
        /// 二进制字符串转换成字节数组
        /// </summary>
        /// <param name="binaryString">要转换的字符，如"00000000 11111111"</param>
        /// <returns></returns>
        private static byte[] BinaryStringToByteArray(string binaryString)
        {
            binaryString = binaryString.Replace(" ", "");

            if ((binaryString.Length % 8) != 0)
                throw new ArgumentException("二进制字符串长度不对");

            byte[] buffer = new byte[binaryString.Length / 8];
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = Convert.ToByte(binaryString.Substring(i * 8, 8).Trim(), 2);
            }
            return buffer;

        }

        /// <summary>
        /// 字节数组转换成十六进制字符串
        /// </summary>
        /// <param name="bytes">要转换的字节数组</param>
        /// <returns></returns>
        private static string ByteArrayToHexStr(byte[] byteArray)
        {
            int capacity = byteArray.Length * 2;
            StringBuilder sb = new StringBuilder(capacity);

            if (byteArray != null)
            {
                for (int i = 0; i < byteArray.Length; i++)
                {
                    sb.Append(byteArray[i].ToString("X2"));
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 十六进制字符串转换成字节数组 
        /// </summary>
        /// <param name="hexString">要转换的字符串</param>
        /// <returns></returns>
        private static byte[] HexStrToByteArray(string hexString)//fef4
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                throw new ArgumentException("十六进制字符串长度不对");
            byte[] buffer = new byte[hexString.Length / 2];
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Trim(), 0x10);
            }
            return buffer;
        }
        #endregion
    }
}
